package com.campusbackend.controller;

import com.campusbackend.entity.EducationBackgrounds;
import com.campusbackend.entity.Result;
import com.campusbackend.entity.Students;
import com.campusbackend.entity.vo.EducationCreateVO;
import com.campusbackend.entity.vo.EducationUpdateVO;
import com.campusbackend.entity.vo.StudentBasicInfoUpdateVO;
import com.campusbackend.entity.vo.StudentQueryVO;
import com.campusbackend.entity.vo.StudentLoginRequestVO;
import com.campusbackend.entity.vo.StudentLoginVO;
import com.campusbackend.entity.vo.StudentRegisterVO;
import com.campusbackend.entity.vo.StudentInfoVO;
import com.campusbackend.service.EducationBackgroundsService;
import com.campusbackend.service.StudentsService;
import com.campusbackend.utils.JwtUtil;
import com.campusbackend.utils.ResultUtil;
import com.campusbackend.utils.ThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 学生用户表 前端控制器
 * </p>
 *
 * @author yezi
 * @since 2025-07-24
 */
@Slf4j
@RestController
@Validated
@RequestMapping("/students")
public class StudentsController {

    @Autowired
    private StudentsService studentsService;

    @Autowired
    private EducationBackgroundsService educationBackgroundsService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    /**
     * 学生登录
     * @param loginVO 登录信息
     * @return 登录结果
     */
    @PostMapping("/login")
    public Result<StudentLoginVO> login(@Valid @RequestBody StudentLoginRequestVO loginVO) {
        log.info("学生登录请求 - studentId: {}", loginVO.getStudentId());

        try {
            // 根据学号查找学生
            Students student = studentsService.findByStudentId(loginVO.getStudentId());

            if (student == null) {
                return ResultUtil.fail("该学号不存在！");
            }

            // 检查账号状态
            if (student.getStatus() == 0) {
                return ResultUtil.fail("账号已被禁用！");
            }


            // 验证密码
            if (!passwordEncoder.matches(loginVO.getPassword(), student.getPassword())) {
                return ResultUtil.fail("密码错误");
            }

            // 检查审核状态
            if (student.getAuditStatus() == 0) {
                return ResultUtil.success(new StudentLoginVO("", 400, (byte) 0));
            } else if (student.getAuditStatus() == 2) {
                return ResultUtil.success(new StudentLoginVO("", 400, (byte) 2));
            }

            // 生成JWT token
            Map<String, Object> claims = new HashMap<>();
            claims.put("id", student.getId());
            claims.put("studentId", student.getStudentId());
            claims.put("username", student.getUsername());
            claims.put("userType", "student");

            String token = JwtUtil.genToken(claims, 1000L * 60 * 60); // 1小时过期

            // 存储到Redis
            ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
            operations.set(token, token, 1, TimeUnit.HOURS);

            log.info("学生登录成功 - studentId: {}, realName: {}", student.getStudentId(), student.getRealName());

            return ResultUtil.success(new StudentLoginVO(token, 200, (byte) 1));

        } catch (Exception e) {
            log.error("学生登录异常", e);
            return ResultUtil.fail("登录过程中发生错误，请稍后重试");
        }
    }

    /**
     * 学生注册
     * @param registerVO 注册信息
     * @return 注册结果
     */
    @PostMapping("/register")
    public Result<String> register(@Valid @RequestBody StudentRegisterVO registerVO) {
        log.info("学生注册请求 - studentId: {}, realName: {}",
                 registerVO.getStudentId(), registerVO.getRealName());

        try {
            String result = studentsService.registerStudent(registerVO);

            // 判断注册是否成功
            if ("注册成功，请等待管理员审核".equals(result)) {
                return ResultUtil.success(result);
            } else {
                return ResultUtil.fail(result);
            }
        } catch (Exception e) {
            log.error("学生注册异常", e);
            return ResultUtil.fail("注册过程中发生错误，请稍后重试");
        }
    }

    /**
     * 获取学生个人信息
     * @return 学生信息
     */
    @GetMapping("/getStudentInfo")
    public Result<Students> getStudentInfo() {
        Map<String, Object> map = ThreadLocalUtil.get();
        String studentId = (String) map.get("studentId");
        Students student = studentsService.findByStudentId(studentId);
        if (student != null) {
            // 不返回密码
            student.setPassword(null);
            return ResultUtil.success(student);
        }
        return ResultUtil.fail("用户不存在");
    }

    /**
     * 智能推荐学生
     * @param college 学院
     * @return 随机推荐的8名学生
     */
    @GetMapping("/recommend")
    public Result<List<StudentQueryVO>> recommendStudents(@RequestParam String college) {
        log.info("智能推荐学生请求 - college: {}", college);
        
        List<Students> students = studentsService.recommendStudents(college);
        List<StudentQueryVO> studentVOs = students.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        return ResultUtil.success(studentVOs);
    }

    /**
     * 精准搜索学生
     * @param college 学院
     * @param keyword 关键词（姓名或学号）
     * @return 符合条件的学生列表
     */
    @GetMapping("/search")
    public Result<List<StudentQueryVO>> searchStudents(@RequestParam String college,
                                                     @RequestParam(required = false) String keyword) {
        log.info("精准搜索学生请求 - college: {}, keyword: {}", college, keyword);
        
        List<Students> students = studentsService.searchStudents(college, keyword);
        List<StudentQueryVO> studentVOs = students.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        return ResultUtil.success(studentVOs);
    }

    /**
     * 获取当前登录学生的综合信息（包含队伍和技能信息）
     * @return 学生综合信息
     */
    @GetMapping("/my-info")
    public Result<StudentInfoVO> getMyInfo() {
        try {
            // 从ThreadLocal获取当前登录学生的ID
            Map<String, Object> claims = ThreadLocalUtil.get();
            Long studentId = Long.valueOf(claims.get("id").toString());
            
            // 获取学生综合信息
            StudentInfoVO studentInfo = studentsService.getStudentInfo(studentId);
            
            log.info("学生 {} 查询个人综合信息成功", studentId);
            return ResultUtil.success(studentInfo);
            
        } catch (Exception e) {
            log.error("获取学生综合信息失败", e);
            return ResultUtil.fail("获取学生信息失败：" + e.getMessage());
        }
    }

    /**
     * 将Students实体转换为StudentQueryVO
     * @param student 学生实体
     * @return 学生查询VO
     */
    private StudentQueryVO convertToVO(Students student) {
        StudentQueryVO vo = new StudentQueryVO();
        BeanUtils.copyProperties(student, vo);
        return vo;
    }

    // ==================== 基础信息管理接口 ====================

    /**
     * 更新学生基本信息
     * @param updateVO 基本信息更新对象
     * @return 更新结果
     */
    @PutMapping("/updateBasicInfo")
    public Result<String> updateBasicInfo(@Valid @RequestBody StudentBasicInfoUpdateVO updateVO) {
        Map<String, Object> map = ThreadLocalUtil.get();
        String studentId = (String) map.get("studentId");
        
        log.info("更新学生基本信息 - studentId: {}, phone: {}, email: {}", 
                 studentId, updateVO.getPhone(), updateVO.getEmail());
        
        try {
            String result = studentsService.updateBasicInfo(studentId, updateVO);
            
            if ("基本信息更新成功".equals(result)) {
                return ResultUtil.success(result);
            } else {
                return ResultUtil.fail(result);
            }
        } catch (Exception e) {
            log.error("更新基本信息异常", e);
            return ResultUtil.fail("更新基本信息时发生错误，请稍后重试");
        }
    }

    // ==================== 教育背景管理接口 ====================

    /**
     * 获取学生的所有教育背景
     * @return 教育背景列表
     */
    @GetMapping("/educations")
    public Result<List<EducationBackgrounds>> getStudentEducations() {
        Map<String, Object> map = ThreadLocalUtil.get();
        Long studentId = ((Number) map.get("id")).longValue();
        
        log.info("获取学生教育背景 - studentId: {}", studentId);
        
        try {
            List<EducationBackgrounds> educations = educationBackgroundsService.getStudentEducations(studentId);
            return ResultUtil.success(educations);
        } catch (Exception e) {
            log.error("获取教育背景异常", e);
            return ResultUtil.fail("获取教育背景时发生错误");
        }
    }

    /**
     * 添加教育背景
     * @param createVO 教育背景创建对象
     * @return 添加结果
     */
    @PostMapping("/educations")
    public Result<String> addStudentEducation(@Valid @RequestBody EducationCreateVO createVO) {
        Map<String, Object> map = ThreadLocalUtil.get();
        Long studentId = ((Number) map.get("id")).longValue();
        
        log.info("添加学生教育背景 - studentId: {}, schoolName: {}", 
                 studentId, createVO.getSchoolName());
        
        try {
            String result = educationBackgroundsService.addStudentEducation(studentId, createVO);
            
            if ("教育背景添加成功".equals(result)) {
                return ResultUtil.success(result);
            } else {
                return ResultUtil.fail(result);
            }
        } catch (Exception e) {
            log.error("添加教育背景异常", e);
            return ResultUtil.fail("添加教育背景时发生错误，请稍后重试");
        }
    }

    /**
     * 更新教育背景
     * @param educationId 教育背景ID
     * @param updateVO 教育背景更新对象
     * @return 更新结果
     */
    @PutMapping("/educations/{educationId}")
    public Result<String> updateStudentEducation(@PathVariable Long educationId, 
                                                 @Valid @RequestBody EducationUpdateVO updateVO) {
        Map<String, Object> map = ThreadLocalUtil.get();
        Long studentId = ((Number) map.get("id")).longValue();
        
        log.info("更新学生教育背景 - studentId: {}, educationId: {}, schoolName: {}", 
                 studentId, educationId, updateVO.getSchoolName());
        
        // 确保路径参数和请求体中的ID一致
        updateVO.setId(educationId);
        
        try {
            String result = educationBackgroundsService.updateStudentEducation(studentId, updateVO);
            
            if ("教育背景更新成功".equals(result)) {
                return ResultUtil.success(result);
            } else {
                return ResultUtil.fail(result);
            }
        } catch (Exception e) {
            log.error("更新教育背景异常", e);
            return ResultUtil.fail("更新教育背景时发生错误，请稍后重试");
        }
    }

    /**
     * 删除教育背景
     * @param educationId 教育背景ID
     * @return 删除结果
     */
    @DeleteMapping("/educations/{educationId}")
    public Result<String> deleteStudentEducation(@PathVariable Long educationId) {
        Map<String, Object> map = ThreadLocalUtil.get();
        Long studentId = ((Number) map.get("id")).longValue();
        
        log.info("删除学生教育背景 - studentId: {}, educationId: {}", studentId, educationId);
        
        try {
            String result = educationBackgroundsService.deleteStudentEducation(studentId, educationId);
            
            if ("教育背景删除成功".equals(result)) {
                return ResultUtil.success(result);
            } else {
                return ResultUtil.fail(result);
            }
        } catch (Exception e) {
            log.error("删除教育背景异常", e);
            return ResultUtil.fail("删除教育背景时发生错误，请稍后重试");
        }
    }
}
